/*
http://www.runoob.com/cplusplus/cpp-exceptions-handling.html
C++ 异常处理
异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况，比如尝试除以零的操作。

异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字：try、catch、throw。

throw: 当问题出现时，程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
catch: 在您想要处理问题的地方，通过异常处理程序捕获异常。catch 关键字用于捕获异常。
try: try 块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。
如果有一个块抛出一个异常，捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码，try 块中的代码被称为保护代码。使用 try/catch 语句的语法如下所示：
*/
#include <iostream>
using namespace std;
 
double division(int a, int b)
{
   if( b == 0 )
   {
      throw "Division by zero condition!";
   }
   if( a== 1) {
       throw "what's this is 1";
   }
   return (a/b);
}

struct MyExceptionOne: public exception {
    const char * what () const throw () {
        return "C++ Exception";
    }
};

class MyException
{
public:
    MyException(const char *message)
        : message_(message)
    {
        cout << "MyException ..." << endl;
    }
    MyException(const MyException &other) : message_(other.message_)
    {
        cout << "Copy MyException ..." << endl;
    }
    virtual ~MyException()
    {
        cout << "~MyException ..." << endl;
    }

    const char *what() const
    {
        return message_.c_str();
    }
private:
    string message_;
};

class MyExceptionD : public MyException
{
public:
    MyExceptionD(const char *message)
        : MyException(message)
    {
        cout << "MyExceptionD ..." << endl;
    }
    MyExceptionD(const MyExceptionD &other)
        : MyException(other)
    {
        cout << "Copy MyExceptionD ..." << endl;
    }
    ~MyExceptionD()
    {
        cout << "~MyExceptionD ..." << endl;
    }
};

void fun(int n) throw (int, MyException, MyExceptionD)
{
    if (n == 1)
    {
        throw 1;
    }
    else if (n == 2)
    {
        throw MyException("test Exception");
    }
    else if (n == 3)
    {
        throw MyExceptionD("test ExceptionD");
    }
}

void fun2() throw()
{

}

int main ()
{
    int x = 1;
    int y = 2;
    double z = 0;

    try {
        z = division(x, y);
        cout << z << endl;
    } catch (const char* msg) {
        cerr << msg << endl;
    }
    // 定义新的异常
    // 您可以通过继承和重载 exception 类来定义新的异常。下面的实例演示了如何使用 std::exception 类来实现自己的异常：
    try {
        throw MyExceptionOne();
    } catch (MyExceptionOne& e) {
        cout << "MyException caught" << endl;
        cout << e.what() << endl;
    } catch (exception& e) {
        cout << "Other error : " << endl;
    }

    // 高级应用
    try {
        fun(2);
    } catch(int n) {
        cout << "catch int ..." << endl;
        cout << "n=" << n << endl;
    } catch(MyExceptionD &e) {
        cout << "catch MyExceptionD ..." << endl;
        cout << e.what() << endl;
    } catch(MyException &e) {
        cout << "catch MyException ..." << endl;
        cout << e.what() << endl;
    }
    return 0;
}